package Factory.Entities;

import Model.Core.Impl.ActorEntity;
import Model.Draw.Coordinate;
import Model.Draw.Entities.ActorDraw;
import Model.Draw.Entities.Impl.EntityJoint;
import Model.Draw.Events.ManifestEntityDoneListener;
import Model.Draw.Events.ManifestElementEvent;
import Model.Draw.Point;
import java.util.ArrayList;
import java.util.List;

/**
 * Projeto de TCC: Editor de Diagramas de comunicação BlueJ
 * @author Jose
 */
public class ActorFactory {
    private List<ManifestEntityDoneListener> listeners;
    
    public ActorFactory(){
        listeners = new ArrayList<ManifestEntityDoneListener>();
    }
    
    public void addListener(ManifestEntityDoneListener listener){
        if(!listeners.contains(listener))
            this.listeners.add(listener);
    }
    
    public void removeListener(ManifestEntityDoneListener listener){
        this.listeners.remove(listener);
    }
    
    public void createEntityGraphicalManifest(ActorEntity actorEntity, Object source, Object target){
        Point startPoint = (Point) source;
        Point finalPoint = (Point) target;
        ActorDraw graphicalManifest = new ActorDraw();
        Point center = defineCenter(startPoint, finalPoint);
        graphicalManifest.setCircle(new EntityJoint(center.getX(), center.getY(), actorEntity), getDistancePoints(startPoint, finalPoint)/2);
        graphicalManifest.setEntity(actorEntity);
        notifyEntityListeners(graphicalManifest);
    }
    
    private void notifyEntityListeners(ActorDraw graphicalManifest) {
        for (ManifestEntityDoneListener listener : listeners) {
            listener.manifestEntityDoneHandler(new ManifestElementEvent(graphicalManifest));
        }
    }
    
    private Point defineCenter(Point start, Point finalP){
        double diffx = start.getX().getCoordinate() - finalP.getX().getCoordinate();
        if(diffx<0)
            diffx = diffx * -1;
        double diffy = start.getY().getCoordinate() - finalP.getY().getCoordinate();
        if(diffy<0)
            diffy = diffy * -1;
        double x,y;
        if(start.getX().getCoordinate()<finalP.getX().getCoordinate())
            x = start.getX().getCoordinate();
        else
            x = finalP.getX().getCoordinate();
        if(start.getY().getCoordinate()<finalP.getY().getCoordinate())
            y = start.getY().getCoordinate();
        else
            y = finalP.getY().getCoordinate();
        x = x + diffx/2;
        y = y + diffy/2;
        return new Point(new Coordinate(x), new Coordinate(y));
    }
    
    private double getDistancePoints(Point p1, Point p2){
        return Math.sqrt(Math.pow((p1.getX().getCoordinate() - p2.getX().getCoordinate()), 2) + Math.pow((p1.getY().getCoordinate() - p2.getY().getCoordinate()), 2));
    }
}